import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'page_flip_types.dart';
import 'page_flip_config.dart';

import 'page_container.dart';

/// 翻页控制器
class PageFlipController extends ChangeNotifier {
  final PageFlipConfig config;
  final int pageCount;
  final PageBuilder pageBuilder;

  late List<AnimationController> _animationControllers;

  int _currentIndex = 0;
  bool _isAnimating = false;
  bool _disposed = false;

  // 回调
  final PageChangeCallback? _onPageChanged;
  final VoidCallback? _onMenuToggle;

  // 手势相关
  bool? _isForward;
  double _netDragDistance = 0.0; // 🆕 净拖拽距离（带符号）

  // 页面容器管理器
  late PageContainerManager _containerManager;

  // 动画控制器 - 只需要3个，对应3个页面容器
  static const int _totalControllers = 3; // 优化：只使用3个动画控制器

  // 提供外部访问动画控制器的方法
  AnimationController? getAnimationController(int pageIndex) {
    // 使用容器管理器获取正确的容器ID
    final containerId = _containerManager.getContainerIdForPage(pageIndex);
    if (containerId == null || containerId >= _totalControllers) return null;
    return _animationControllers[containerId];
  }

  /// 获取页面容器管理器
  PageContainerManager get containerManager => _containerManager;

  PageFlipController({
    required this.config,
    required this.pageCount,
    required this.pageBuilder,
    PageChangeCallback? onPageChanged,
    VoidCallback? onMenuToggle,
  })  : _onPageChanged = onPageChanged,
        _onMenuToggle = onMenuToggle {
    // 初始化页面容器管理器
    _containerManager = PageContainerManager(pageCount: pageCount);
  }

  /// 初始化动画控制器
  void initAnimationControllers(TickerProvider tickerProvider) {
    _animationControllers = List.generate(
      _totalControllers,
      (index) => AnimationController(
        value: 1.0, // 默认隐藏状态
        duration: Duration(milliseconds: config.animationDuration),
        vsync: tickerProvider,
      ),
    );

    // 设置当前页面的控制器为显示状态
    final currentContainerId =
        _containerManager.getContainerIdForPage(_currentIndex);
    if (currentContainerId != null && currentContainerId < _totalControllers) {
      _animationControllers[currentContainerId].value = 0.0; // 当前页显示
    }
  }

  // Getters
  int get currentIndex => _currentIndex;
  int get currentPage => _currentIndex; // 返回内部索引，与currentIndex保持一致
  bool get isAnimating => _isAnimating;
  bool get isFirstPage => _currentIndex <= 0;
  bool get isLastPage => _currentIndex >= pageCount - 1;
  int get firstIndex => 0;
  int get lastIndex => pageCount - 1;

  /// 获取指定索引的动画位置
  double getAnimationPosition(int index) {
    if (index < 0 || index >= _animationControllers.length) return 1.0;
    return _animationControllers[index].value;
  }

  /// 跳转到指定页面
  Future<void> goToPage(int index, {bool animate = true}) async {
    if (index < 0 || index >= pageCount || index == _currentIndex) return;
    if (_isAnimating) return;

    final oldIndex = _currentIndex;
    final targetIndex = index.clamp(0, pageCount - 1);

    // 判断是否为相邻页面翻页
    final isAdjacentPage = (targetIndex - oldIndex).abs() == 1;

    if (animate && isAdjacentPage) {
      // 相邻页面使用动画翻页
      await _animateToAdjacentPage(oldIndex, targetIndex);
    } else {
      // 大范围跳转或禁用动画时直接更新
      _currentIndex = targetIndex;
      _containerManager.setCurrentPageIndex(_currentIndex);
    }

    _onPageChanged?.call(_currentIndex);
    notifyListeners();
  }

  /// 下一页（使用动画）
  Future<void> nextPage() async {
    if (isLastPage || _isAnimating) return;
    await goToPage(_currentIndex + 1, animate: true);
  }

  /// 上一页（使用动画）
  Future<void> previousPage() async {
    if (isFirstPage || _isAnimating) return;
    await goToPage(_currentIndex - 1, animate: true);
  }

  /// 🆕 处理手势开始
  void handleDragStart(DragStartDetails details) {
    if (!config.enableGestures || _isAnimating) return;

    // 重置手势状态
    _isForward = null;
    _netDragDistance = 0.0;

    debugPrint('🚀 手势开始: position=${details.globalPosition.dx}');
  }

  /// 处理手势翻页
  void handleDragUpdate(DragUpdateDetails details, Size screenSize) {
    if (!config.enableGestures || _isAnimating) return;

    final primaryDelta = details.primaryDelta ?? 0.0;
    final screenWidth = screenSize.width;

    debugPrint('手势更新: delta=${details.delta.dx}, primaryDelta=$primaryDelta');

    // 🆕 初始化拖拽起始位置
    if (_isForward == null) {
      _netDragDistance = 0.0;
    }

    // 🆕 累积净位移（带符号）
    _netDragDistance += primaryDelta;

    // 🆕 实时检测当前拖拽方向
    final currentDirection = _netDragDistance < 0; // 负值=向左=下一页，正值=向右=上一页

    // 🆕 第一次确定方向或检测到方向切换
    if (_isForward == null || _isForward != currentDirection) {
      _isForward = currentDirection;
      debugPrint(
          '🔄 更新拖拽方向: ${_isForward! ? "下一页" : "上一页"} (净位移: $_netDragDistance)');
    }

    // 计算目标页面索引
    final targetIndex = _isForward! ? _currentIndex + 1 : _currentIndex - 1;
    if (targetIndex < 0 || targetIndex >= pageCount) {
      debugPrint('目标页面超出范围: $targetIndex');
      return;
    }

    // 获取目标页面对应的容器索引
    final targetContainerId =
        _containerManager.getContainerIdForPage(targetIndex);
    if (targetContainerId == null) {
      debugPrint('目标页面 $targetIndex 没有对应的容器');
      return;
    }

    // 🆕 计算拖拽进度：基于净位移的绝对值
    final absDragDistance = _netDragDistance.abs();
    final dragProgress = (absDragDistance / screenWidth).clamp(0.0, 1.0);

    // 更新目标页面的动画控制器
    final controller = _animationControllers[targetContainerId];
    final newValue = (1.0 - dragProgress).clamp(0.0, 1.0);

    debugPrint(
        '净位移: $_netDragDistance, 拖拽进度: $dragProgress, 动画值: ${controller.value} -> $newValue');

    controller.value = newValue;
    notifyListeners();
  }

  /// 处理手势结束
  Future<void> handleDragEnd(DragEndDetails details) async {
    if (!config.enableGestures || _isForward == null) return;

    debugPrint('手势结束: velocity=${details.velocity.pixelsPerSecond.dx}');

    final velocity = details.velocity.pixelsPerSecond.dx.abs();
    final targetIndex = _isForward! ? _currentIndex + 1 : _currentIndex - 1;

    if (targetIndex < 0 || targetIndex >= pageCount) {
      debugPrint('目标页面超出范围，重置动画');
      await _resetAnimation();
      _isForward = null;
      _netDragDistance = 0.0; // 🆕 重置净位移
      return;
    }

    // 获取目标页面对应的容器索引
    final targetContainerId =
        _containerManager.getContainerIdForPage(targetIndex);
    if (targetContainerId == null) {
      debugPrint('目标页面 $targetIndex 没有对应的容器，重置动画');
      await _resetAnimation();
      _isForward = null;
      _netDragDistance = 0.0; // 🆕 重置净位移
      return;
    }

    final controller = _animationControllers[targetContainerId];

    // 判断是否应该完成翻页：
    // 1. 高速滑动 (velocity > 配置的速度阈值)
    // 2. 滑动距离超过配置的距离阈值 (animationValue < 距离阈值)
    final shouldFlip = velocity > config.flipVelocityThreshold ||
        controller.value < (1.0 - config.flipDistanceThreshold);

    debugPrint(
        '是否翻页: $shouldFlip (velocity: $velocity, animValue: ${controller.value})');

    if (shouldFlip) {
      // 完成翻页动画
      _isAnimating = true;
      try {
        // 动画到完全显示状态 (0.0)
        await controller.animateTo(0.0);

        // 更新页面索引和容器映射
        _currentIndex = targetIndex;
        _containerManager.setCurrentPageIndex(_currentIndex);

        // 重置所有动画控制器的正确状态
        for (int i = 0; i < _totalControllers; i++) {
          final pageIndex = _containerManager.getContainerPageIndex(i);
          if (pageIndex == _currentIndex) {
            // 当前页面对应的容器应该显示 (0.0)
            _animationControllers[i].value = 0.0;
            debugPrint('设置容器$i为显示状态 (页面$pageIndex)');
          } else {
            // 其他容器隐藏 (1.0)
            _animationControllers[i].value = 1.0;
            debugPrint('设置容器$i为隐藏状态 (页面$pageIndex)');
          }
        }

        _onPageChanged?.call(_currentIndex);

        debugPrint('翻页完成，当前页: $_currentIndex');
      } finally {
        _isAnimating = false;
      }
    } else {
      // 取消翻页，恢复到原始状态
      debugPrint('取消翻页，恢复原状态');
      await _resetAnimation();
    }

    _isForward = null;
    _netDragDistance = 0.0; // 🆕 重置净位移
    notifyListeners();
  }

  /// 处理点击
  void handleTap(TapUpDetails details, Size screenSize) {
    if (!config.enableGestures || _isAnimating) return;

    final tapX = details.globalPosition.dx;
    final screenWidth = screenSize.width;
    final screenHeight = screenSize.height;

    // 检查是否点击菜单区域
    final menuZoneSize = screenSize * config.menuZoneRatio;
    final menuZoneRect = Rect.fromCenter(
      center: Offset(screenWidth / 2, screenHeight / 2),
      width: menuZoneSize.width,
      height: menuZoneSize.height,
    );

    if (menuZoneRect.contains(details.globalPosition)) {
      _onMenuToggle?.call();
      return;
    }

    // 检查是否启用点击切换页面
    if (!config.enableTapToFlip) {
      return; // 如果禁用点击切换，直接返回
    }

    // 左右点击翻页
    final isLeftTap = tapX < screenWidth / 2;
    if (config.oneHandMode) {
      // 单手模式：左右行为相反
      if (isLeftTap) {
        nextPage();
      } else {
        previousPage();
      }
    } else {
      // 正常模式
      if (isLeftTap) {
        previousPage();
      } else {
        nextPage();
      }
    }
  }

  /// 处理键盘事件
  void handleKeyPress(KeyEvent event) {
    if (!config.enableKeyboard || _isAnimating) return;
    if (event is! KeyDownEvent) return;

    switch (event.logicalKey) {
      case LogicalKeyboardKey.arrowLeft:
      case LogicalKeyboardKey.arrowUp:
        previousPage();
        break;
      case LogicalKeyboardKey.arrowRight:
      case LogicalKeyboardKey.arrowDown:
        nextPage();
        break;
      case LogicalKeyboardKey.home:
        goToPage(0);
        break;
      case LogicalKeyboardKey.end:
        goToPage(pageCount - 1);
        break;
      case LogicalKeyboardKey.enter:
      case LogicalKeyboardKey.numpadEnter:
        _onMenuToggle?.call();
        break;
    }
  }

  /// 动画到相邻页面（与手势滑动动画一致）
  Future<void> _animateToAdjacentPage(int fromIndex, int toIndex) async {
    _isAnimating = true;

    try {
      final isForward = toIndex > fromIndex;
      debugPrint(
          '🎬 开始相邻页面动画: $fromIndex -> $toIndex (${isForward ? "向前" : "向后"})');

      // 先确保目标页面在容器中
      final targetContainerId =
          _containerManager.getContainerIdForPage(toIndex);
      if (targetContainerId == null) {
        debugPrint('❌ 目标页面 $toIndex 没有对应的容器，执行直接跳转');
        _currentIndex = toIndex;
        _containerManager.setCurrentPageIndex(_currentIndex);
        return;
      }

      final targetController = _animationControllers[targetContainerId];

      debugPrint(
          '🎯 目标容器: $targetContainerId (动画值: ${targetController.value})');

      // 确保目标页面处于隐藏状态（模拟手势滑动开始状态）
      targetController.value = 1.0;

      // 立即通知UI更新以显示初始状态
      notifyListeners();

      debugPrint('🚀 开始执行翻页动画...');

      // 添加动画监听器以实时更新UI
      void animationListener() {
        notifyListeners();
      }

      targetController.addListener(animationListener);

      try {
        // 只对目标页面执行动画：从隐藏状态(1.0)到显示状态(0.0)
        // 这与手势滑动动画完全一致
        await targetController.animateTo(0.0);
      } finally {
        // 移除监听器
        targetController.removeListener(animationListener);
      }

      debugPrint('✅ 翻页动画执行完成');
      debugPrint('📊 目标页动画值: ${targetController.value}');

      // 更新当前页面索引
      _currentIndex = toIndex;
      _containerManager.setCurrentPageIndex(_currentIndex);

      // 重置所有动画控制器的状态
      for (int i = 0; i < _totalControllers; i++) {
        final pageIndex = _containerManager.getContainerPageIndex(i);
        if (pageIndex == _currentIndex) {
          _animationControllers[i].value = 0.0; // 当前页显示
        } else {
          _animationControllers[i].value = 1.0; // 其他页隐藏
        }
      }

      debugPrint('🎉 相邻页面动画完成，当前页: $_currentIndex');
    } finally {
      _isAnimating = false;
    }

    // 通知UI更新
    notifyListeners();
  }

  /// 动画到指定页面（用于大范围跳转的淡入效果）
  Future<void> _animateToPage(int fromIndex, int toIndex) async {
    _isAnimating = true;

    try {
      // 直接更新到目标页面
      _currentIndex = toIndex;
      _containerManager.setCurrentPageIndex(_currentIndex);

      // 重置所有控制器到隐藏状态
      for (int i = 0; i < _totalControllers; i++) {
        _animationControllers[i].value = 1.0;
      }

      // 找到当前页面对应的容器（应该是容器1）
      final currentContainerId =
          _containerManager.getContainerIdForPage(_currentIndex);
      if (currentContainerId != null) {
        final controller = _animationControllers[currentContainerId];

        // 淡入动画：从隐藏到显示
        await controller.animateTo(0.0);
      } else {
        // 如果没有找到对应容器，直接显示
        _animationControllers[1].value = 0.0; // 使用容器1作为默认当前页容器
      }
    } finally {
      _isAnimating = false;
    }
  }

  /// 重置动画
  Future<void> _resetAnimation() async {
    _isAnimating = true;

    try {
      debugPrint('重置所有动画控制器到隐藏状态');
      // 将所有动画控制器重置到隐藏状态 (1.0)
      final futures = <Future>[];
      for (int i = 0; i < _totalControllers; i++) {
        if (_animationControllers[i].value != 1.0) {
          futures.add(_animationControllers[i].animateTo(1.0));
        }
      }
      await Future.wait(futures);
    } finally {
      _isAnimating = false;
      _isForward = null;
    }
  }

  @override
  void dispose() {
    if (_disposed) return;
    _disposed = true;

    for (final controller in _animationControllers) {
      controller.dispose();
    }
    super.dispose();
  }
}
